package com.gcsoftware.web.mapper.elasticsearch;

import com.gcsoftware.utils.elasticsearch.StringUtils;
import com.gcsoftware.web.beans.elasticsearchData.Agg;
import com.gcsoftware.web.beans.elasticsearchData.Hit;
import com.gcsoftware.web.beans.returnPage.ApiCount;
import com.gcsoftware.web.beans.returnPage.Buckets;
import com.gcsoftware.web.service.elasticsearch.impl.TemplateRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

import static com.gcsoftware.configs.AppConstants.Elasticsearch.*;
import static com.gcsoftware.configs.AppConstants.Sys.SYS_MEASURE_DAY;
import static com.gcsoftware.configs.AppConstants.Sys.SYS_MEASURE_SECOND;

/**
 * 报表
 * @author czp
 * data : 2018-04-11
 */
@Repository
public class ReportDao<T> {
    @Autowired
    private TemplateRepository<T> template;

    @Value("${elasticsearch.index}")
    private String index;

    public long asensitiveItemCount(String item, String field, String split, String range) {
        StringBuffer query = new StringBuffer();
        query.append("{\"bool\":{\"must\":[{");
        if (split.equals(ES_MATCH_PHRASE_TAG.getValue()) && !"".equals(item)) {
            query.append("\"")
                 .append(ES_MATCH_PHRASE_TAG.getValue())
                 .append("\":{\"")
                 .append(field)
                 .append("\":\"")
                 .append(item)
                 .append("\"}},")
                 .append(StringUtils.queryPageRange(range, SYS_MEASURE_DAY.getValue()))
                 .append("]}}");
        } else if (split.equals(ES_TERM_TAG.getValue()) && !"".equals(item)) {
            query.append("\"term\":{\"")
                 .append(field)
                 .append(".keyword\":\"")
                 .append(item)
                 .append("\"}},")
                 .append(StringUtils.queryPageRange(range, SYS_MEASURE_DAY.getValue()))
                 .append("]}}");
        } else {
            query.append("}]}}");
        }
        return template.fieldCount(index, null, query.toString());
    }

    public Page apiCountReport(Pageable page, String appName, String apiName,
                               String range, String sord) {
        StringBuffer rQuery = new StringBuffer();
        List<String> fields = new ArrayList<>();
        fields.add(ES_APP_NAME.getValue());
        fields.add(ES_APP_ID.getValue());
        fields.add(ES_API_NAME.getValue());
        fields.add(ES_API_ID.getValue());
        fields.add(ES_CREATE_TIME.getValue());
        rQuery.append("{\"bool\":{\"must\":[")
              .append(StringUtils.queryTerms(apiName, appName))
              .append(",")
              .append(StringUtils.queryPageRange(range, SYS_MEASURE_DAY.getValue()))
              .append("]}}");
        return template.queryDslByPage(index, null, rQuery.toString(), page, fields, sord);
    }

    public T apiCountNumber(String range) {
        StringBuffer aggs = new StringBuffer();
        String query = StringUtils.queryGroupRange(range, null, SYS_MEASURE_SECOND.getValue());
        aggs.append("{\"").append(ES_API_NAME_GROUPS.getValue())
            .append("\":{\"terms\":{\"field\":\"").append(ES_API_NAME.getValue())
            .append(".keyword\",\"size\":1000,\"order\":{\"_count\":\"desc\"}}}}");
        return template.queryDslGroup(index, null, query, aggs.toString(), ES_API_NAME_GROUPS.getValue());
    }

    public Object asensitiveItemCharts(String asensitiveItem, String range) {
        StringBuffer aggs = new StringBuffer();
        String query = StringUtils.queryGroupRange(range, asensitiveItem, SYS_MEASURE_DAY.getValue());
        aggs.append("{\"")
            .append(ES_ITEM_GROUPS.getValue())
            .append("\":{\"date_histogram\":")
            .append("{\"field\":\"@timestamp\",\"interval\":\"1d\",\"format\":\"yyyy-MM-dd\",\"min_doc_count\":1}")
            .append("}}");
        return template.queryDslGroup(index, null, query, aggs.toString(), ES_ITEM_GROUPS.getValue());
    }

    public T getApiNames() {
        String query = "{}";
        StringBuffer aggs =  new StringBuffer();
        aggs.append("{\"").append(ES_API_NAME_GROUPS.getValue())
            .append("\":{\"terms\":{\"field\":\"").append(ES_API_NAME.getValue())
            .append(".keyword\",\"size\":1000,\"order\":{\"_count\":\"desc\"}}}}");
        return template.queryDslGroup(index, null, query, aggs.toString(), ES_API_NAME_GROUPS.getValue());
    }

    public T getAppNames() {
        String query = "{}";
        StringBuffer aggs =  new StringBuffer();
        aggs.append("{\"").append(ES_APP_NAME_GROUPS.getValue())
            .append("\":{\"terms\":{\"field\":\"").append(ES_APP_NAME.getValue())
            .append(".keyword\",\"size\":1000,\"order\":{\"_count\":\"desc\"}}}}");
        return template.queryDslGroup(index, null, query, aggs.toString(), ES_APP_NAME_GROUPS.getValue());
    }

    public Object apiCountCharts(String appName, String apiName, String range) {
        StringBuffer aggs = new StringBuffer();
        StringBuffer query = new StringBuffer();
        query.append("{\"bool\":{\"must\":[")
             .append(StringUtils.queryPageRange(range, SYS_MEASURE_SECOND.getValue()))
             .append(",")
             .append(StringUtils.queryTerms(apiName, appName))
             .append("]}}");
        aggs.append("{\"")
            .append(ES_ITEM_GROUPS.getValue())
            .append("\":{\"date_histogram\":")
            .append("{\"field\":\"@timestamp\",\"interval\":\"1d\",\"format\":\"yyyy-MM-dd\",\"min_doc_count\":1}")
            .append("}}");
        return template.queryDslGroup(index, null, query.toString(), aggs.toString(), ES_ITEM_GROUPS.getValue());
    }
}
